/**
 * @author 廖俊涵
*/

#pragma once


#include <opencv2/core.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <seeta/FaceLandmarker.h>
#include <seeta/FaceDetector.h>
#include <seeta/FaceAntiSpoofing.h>
#include <seeta/Common/Struct.h>
#include <seeta/CTrackingFaceInfo.h>
#include <seeta/FaceTracker.h>
#include <seeta/FaceRecognizer.h>
#include <seeta/QualityAssessor.h>
#include <seeta/QualityOfPoseEx.h>
#include <seeta/QualityOfLBN.h>
#include <seeta/EyeStateDetector.h>

#include <map>
#include <fstream>
#include <iostream>
#include <stdio.h>
#define NO_RUN 0;
#define RUNNING 1
#define MOVING 2;
#define	COMPLISH 3;
#define EXCEPTION 4;
typedef std::pair<seeta::EyeStateDetector::EYE_STATE,
	seeta::EyeStateDetector::EYE_STATE> EYESTATE_PAIR ;
class FaceAction
{
public:
	const int EYE_LEFT_BLINK_ACTION = 1;
	const int EYE_RIGHT_BLINK_ACTION = 2;
	const int EYE_ALL_BLINK_ACTION = 3;
	const int TURN_LEFT_ACTION = 4;
	const int TURN_RIGHT_ACTION = 5;
	const int TURN_UP_ACTION = 6;
	const int MOUTH_ACTION = 7;
	const int EYE_ROTATION_LEFT_ACTION = 8;
	const int EYE_ROTATION_RIGHT_ACTION = 9;


	int INIT = 0;
	std::string modelpath;
	seeta::QualityOfPoseEx* QP;
	seeta::FaceDetector* FD;
	seeta::FaceLandmarker* flm68;
	seeta::FaceLandmarker* flm5;
	seeta::EyeStateDetector* ESD;
	seeta::v3::QualityResult checkRes;
	cv::Mat imgMat;
	cv::Mat imgMat_gray;
	SeetaImageData* imgData_gray;
	SeetaImageData* imgData;
	SeetaRect* fRect;
	std::vector<SeetaPointF>* i_points5;
	std::vector<SeetaPointF>* points5;
	std::vector<SeetaPointF>* i_points68;
	std::vector<SeetaPointF>* points68;
	FaceAction(std::string modelpath) {
		contructContent(modelpath);
	}
	FaceAction(SeetaImageData& imgData, SeetaRect& fRect, std::string modelpath);
	FaceAction(cv::Mat& imgMat, SeetaRect& fRect, std::string modelpath);

	void contructContent(std::string modelpath);
	void init_points(std::vector<SeetaPointF>& i_points5, std::vector<SeetaPointF>& i_points68);
	void setPoints(std::vector<SeetaPointF>& points);
	void init_ImageData(SeetaImageData& imgData, SeetaRect& fRect);
	void init_Mat(cv::Mat& imgMat, SeetaRect& fRect);
	void setPoints68();
	void setPoints5();
	cv::Mat drawPoints(int pointsSize, bool showNumber = false);
	cv::Mat drawPoints(int pointsSize, cv::Mat& mat, bool showNumber = false);


	int LEFT = 0;
	int RIGHT = 1;
	int EYE_ROTATION_LEFT = 0;
	int EYE_ROTATION_RIGHT = 0;
	cv::Point LEye_InitCenter;
	cv::Point REye_InitCenter;
	cv::Point LEye_RltCenter;
	cv::Point REye_RltCenter;
	cv::Point LEye_Center;
	cv::Point REye_Center;
	cv::Mat EFrame_left;
	cv::Mat EFrame_right;
	cv::Mat getEyeFrame(int eye);
	cv::Mat getIrisFrame(cv::Mat& eye_frame, int threshould);
	float getIrisSize(cv::Mat iris_frame);
	int getBestThreshould(cv::Mat eye_frame);
	void getEyeCenter();
	cv::Mat showEyeCenter(cv::Mat& mat);
	int checkEyeRotation();

	int INIT_TURNLEFT_ANGLE;
	int INIT_TURNRIGHT_ANGLE;
	int INIT_TURNUP_ANGLE;
	int TURN_LEFT = 0;
	int TURN_RIGHT = 0;
	int TURN_DOWN = 0;
	int TURN_UP = 0;
	int LEFT_FRAMES = 0;
	int RIGHT_FRAMES = 0;
	int UP_FRAMES = 0;
	int distance(int d1, int d2);
	int calcAngle(int d1, int d2, int d3);
	int checkTurn(int turnType);
	int checkAllTurn();


	int LEFT_BLINK = 0;
	int RIGHT_BLINK = 0;
	int ALL_BLINK = 0;
	EYESTATE_PAIR getEyestate();
	int checkEyes(seeta::EyeStateDetector::EYE_STATE leftstate, 
		seeta::EyeStateDetector::EYE_STATE rightstate, int eyeType);
	int checkEyes(int eyeType);
	int checkAllEyes();


	int OPEN_MOUTH = 0;
	int checkMouth();

	int checkAllAction();
};

